home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-03-02 | 39.0 KB | 1,218 lines | [TEXT/MPS ] |
- /******************************************************************************
-
- NAME:
- Infinity Windoid 2.2
-
- WRITTEN BY:
- Troy Gaul
- Infinity Systems
-
- © 1991-93 Infinity Systems
- All rights reserved.
-
- DESCRIPTION:
- This file contains the source for a standalone code resource that
- conforms to a Window DEFinition (WDEF), as defined by Apple Computer
- in Inside Macintosh.
-
- It provides a 'windoid' appearance. A windoid is a floating window
- that appears above document windows in an application and is commonly
- used for things like tool palettes, information windows, and the like.
-
- The WDEF included in the ResEdit file can be used as-is, but if a zoom
- box is to be used, you will probably want to change the behavior of
- what is included (by default, it zooms smaller rather than larger as
- described below). This WDEF is created for System 6 and later, but it
- would be easy to modify it for earlier systems if this is important.
-
- FEATURES:
- • Supports System 7-style coloring of windows.
- • In System 7, the tinge color set by the user in the Color control
- panel is used.
- • Close box can be enabled from NewWindow by setting goAwayFlag.
- • Zoom box (special case) implemented, utilized by adding zoomDocProc
- to the proc ID used to create the windoid.
- • Title bar can appear along the left of the window if 1 is added to
- the proc ID (with or without a zoom box).
- • For MacApp users, the left/top behavior of the proc ID can be
- switched.
- • System 6 coloring scheme is also supported (can be set in Kolor or
- a similar control panel).
- • In System 7, DeviceLoop is used so the windoid will be drawn
- correctly even when it crosses monitors of differing depths.
- • In System 7, indexed color tables are checked to see if there are
- enough different colors to display the color version (like the
- system WDEF).
-
- -------------------------------------------------------------------------------
-
- VERSION HISTORY:
- 2.2: (Mar 93)
- • First publicly distributed version.
- • Extensive comments added to facilitate understanding and
- modification by others.
- • Added support for MacApp-style varcodes.
- • Bug in way inColor was determined (needed to do a bit-shift
- before anding with gdFlags) fixed.
- • Removed StuffHex of strings used for title bar pattern, now
- calculates these values.
- • Fixed bug in logic of how MixColor was calculating the mixture.
- • Support for compilation in THINK C 5.0.
- • Added way to build so the window are always hilighted
-
- 2.1: (Nov 92)
- • Reduced code size by making sure no extra code was being linked
- by MPW.
- • Removed use of Gestalt for code size reasons.
- • Ended the use of function pointers since no advantage was being
- gained by their use.
- • Added support for determining if enough different colors were
- available to do System 7-style color like Apple's does.
-
- 2.0: (January 92)
- • Rewritten in C.
- • Conditional compilation of some features to facilitate a
- reduced-size version and one that could be distributed.
-
- 1.2: (June 91)
- • System 6 color support added. This feature was suggested by
- Richard R. Harms.
- • DeviceLoop support added. (Thanks, MacDTS.)
-
- 1.1: (May 91)
- • Support for System 7-style color titlebars.
-
- 1.0: (May 91)
- • Original version, written in Pascal and based on original
- assembly language, black-and-white windoid WDEF used in
- MicroFrontier products, which was written by Tom Pinkerton.
-
- -------------------------------------------------------------------------------
-
- MAKING WINDOWS FLOAT:
- I just wanted to point out that the windoid WDEF provided here will
- simply give you a window with a smaller, palette-style titlebar. It
- does NOT make that window float above all the others in your program.
- This behavior (which is almost always associated with windows using
- this sort of WDEF) must be implemented into the application's window-
- handling code. This is not necessarily a straightforward thing to do,
- as there is no easy, Apple-provided way. It is not difficult, but some
- care must be taken.
-
- RELEASE/USAGE INFORMATION:
- This WDEF is used in commercial applications by MicroFrontier, Inc.,
- including (but not limited to) Enhance 2.0, Color It! 2.0, and Paint
- It! 1.0.
-
- MicroFrontier and I are hereby making this WDEF available for use in
- other products, commercial or not, with the understanding that you may
- modify the code in whatever ways are necessary for use in your
- product (such as adding a grow box, changing zoom behavior, etc).
- MicroFrontier and Troy Gaul, however, will take no responsibility
- for problems caused by the use of this code.
-
- If you do have any problems, though, don't be afraid do contact me
- by one of the ways listed below. I'll be glad to help. Also, if
- you make modifications to the WDEF, I would appreciate it if you
- would let me know about them. If there are changes that might benefit
- others, I might implement them for a future release.
-
- I do plan to support this WDEF in the future. If you have problems,
- compatibility or otherwise, or if you see a glaring error in the code,
- let me know, and a revision will be made. I will also keep a list of
- e-mail addresses of those people who tell me they are using the
- WDEF and want to receive updates. When a new version is released,
- it (or at least notification of it) will be sent to all such users.
-
- ACKNOWLEDGEMENTS:
- I'd like to pay special thanks to Tom Pinkerton, who wrote a windoid
- WDEF from which I created this one and who taught me how to program the
- Macintosh, and to Richard Harms, who kept pushing me to add features
- (such as the System 6 color support, support for 68000 machines, and
- the MacApp-style), told me about the bugs he found, and prodded me to
- release a version to the public. Also, thanks to MicroFrontier for
- letting me release this WDEF for use by others.
-
- -------------------------------------------------------------------------------
-
- HOW TO CONTACT THE AUTHOR:
- To 'register' your copy of this WDEF if you plan to use it and want
- updates in the future, send me your e-mail address(es). Also, use
- these to contact me with any problems.
-
- Troy Gaul
- Infinity Systems
- 1101 25th Street, #5
- Des Moines, IA 50311
- (515) 255-2080
-
- MicroFrontier, Inc.
- 3401 101st Street
- Suite E
- Des Moines, IA 50322
- (515) 270-8109
-
- Internet: tag002@acad.drake.edu (until May 93)
- t-gaul@grayhawk.rent.com
- ntwing@aol.com
- mfrontier@applelink.apple.com
- mfrontier@aol.com
-
- Applelink: mfrontier
-
- America Online: ntwing
- mfrontier
-
- FAX: (515) 278-6828
-
- ******************************************************************************/
-
-
- //*****************************************************************************
- // Include files
- //-----------------------------------------------------------------------------
-
- #define SystemSixOrLater 1
- // This is used so that we can cut down on the code size in MPW. If you
- // think support for earlier systems is important, get rid of this, but
- // make sure you do your own testing, I have not tried it with any earlier
- // systems.
- // Note: for this define to work under THINK C, MacHeaders should NOT
- // be included (and are not in the included project file).
-
- //-----------------------------------------------------------------------------
-
- #include <Memory.h>
- #include <QuickDraw.h>
- #include <OSUtils.h>
- #include <Windows.h>
- #include <Palettes.h>
- #include <ToolUtils.h>
- #include <Desk.h>
-
- //*****************************************************************************
- // Conditional Compilation Options
- /*-----------------------------------------------------------------------------
-
- The #define's you may make include:
-
- MFI_ZOOMBOX - This is the special behavior of the zoombox in palettes
- in products from MicroFrontier, Inc. This involves
- shrinking the palette to the titlebar + a strip that
- will show the palette's name (note: this requires some
- special application coding to implement). Also, the code
- inclosed in these conditionals may be a good start for
- coding your own zoom routines.
-
- ALLOW_VERT - This determines if the code that is compiled will support
- a palette that has a vertical title bar along the left
- side of the window (rather than the top). To create such
- a window, add one to the varcode that is used.
-
- MACAPP_STYLE - This determines if the varcodes that are supported are
- the one's I consider 'normal' or the ones MacApp's
- windoid WDEF knows about. Note, however, that this code
- only supports the 'smaller', title-less version that
- is available in MacApp's.
-
- ALWAYS_HILITE This will cause a windoid to be created that will always
- draw its title bar with gadgets and all. Normally, the
- windoid will draw the titlebar and frame in gray and
- empty when the window is not hilighted (like normal
- windows). Some programs, however, don't keep their
- windoids properly hilighted, so this will make them
- appear to always be active.
-
- -----------------------------------------------------------------------------*/
-
- #define MFI_ZOOMBOX
- #define ALLOW_VERT
-
- //*****************************************************************************
- // Constants
- //-----------------------------------------------------------------------------
-
- #define wpTitleHeight 11
- // This is the height of the windoid's titlebar.
-
- #define wpSmallZoom 12
- // This is the size of the area under (or right of) the title bar when the
- // MFI zoombox is in its reduced mode.
-
- //-----------------------------------------------------------------------------
- // Color table tinge percentage constants
-
- #define wTitleBarLightPct 0x01
- #define wTitleBarDarkPct 0x08
- #define wCloseBoxColor 0x05
- #define wXedBoxPct 0x08
- #define wInactiveFramePct 0x0A
-
- //-----------------------------------------------------------------------------
- // Color table constants
-
- enum {
- wHiliteColorLight = 5,
- wHiliteColorDark,
- wTitleBarLight,
- wTitleBarDark,
- wDialogLight,
- wDialogDark,
- wTingeLight,
- wTingeDark
- };
- // These are the constants defined in the Apple technical note regarding
- // Color, Windows, and System 7. Last I checked, they weren't in an Apple
- // header file. (But the ones < 5 are, from the previous, pre-System 7
- // coloring scheme.)
-
- //-----------------------------------------------------------------------------
- // Style variation constants
-
- enum {
- blackandwhite = 0,
- sys7color,
- sys6color
- };
- // These constants represent the three types of window 'colorings' we
- // support.
-
- //-----------------------------------------------------------------------------
- // MacApp style variations
-
- #define kMacApp_toggleTBar 0x01 // bit 0 tells us whether to hilite/unhilite title bar
- #define kMacApp_hasTallTBar 0x02 // bit 1 is tall title bar bit (unsupported)
- #define kMacApp_hasGrow 0x04 // bit 2 is grow bit (unsupported)
- #define kMacApp_hasZoom 0x08 // bit 3 is zoom bit
-
- //*****************************************************************************
- // Structures
- //-----------------------------------------------------------------------------
-
- typedef struct WindoidData {
- WStateData wState;
- unsigned int closeToggle : 1;
- unsigned int isSystem7 : 1;
- unsigned int hasCQD : 1;
- unsigned int isHoriz : 1;
- unsigned int ignoreHilite: 1;
- #ifdef MFI_ZOOMBOX
- unsigned int zoomToggle : 1;
- unsigned int hasZoom : 1;
- #endif
- } WindoidData, *WindoidDataPtr, **WindoidDataHandle;
-
- #define WindData (**(WindoidDataHandle)(theWindow->dataHandle))
- // This macro is used so I can access the 'globals' easily. Note: the
- // variable containing the window must be theWindow, and it must be in
- // scope at the time of the usage of this macro.
- // Also, they aren't REALLY globals, becuase they're kept for EACH window,
- // which is why I use the :1 notation, trying to keep this as small as
- // possible.)
-
- //-----------------------------------------------------------------------------
-
- typedef struct WDLDataRec {
- WindowPeek wdlWindow;
- long wdlParam;
- } WDLDataRec, *WDLDataPtr;
- // This information is used for the DeviceLoop we set up.
-
- //*****************************************************************************
- // Function Prototypes
- //-----------------------------------------------------------------------------
-
- void DoWInit( short varCode, WindowPeek theWindow, long param );
- void DoWDispose( WindowPeek theWindow, long param );
- long DoWHit( WindowPeek theWindow, long param );
- void DoWDraw ( WindowPeek theWindow, long param );
- void DoWCalcRgns ( WindowPeek theWindow, long param );
-
- //*****************************************************************************
- // Windoid Main Function
- //-----------------------------------------------------------------------------
- // This is the main entry point for all calls to this code resource. It
- // dispatches to routines that correspond to the message it is given.
- //-----------------------------------------------------------------------------
-
- pascal long main( short varCode, WindowPeek theWindow,
- short message, long param ) {
- GrafPtr wpSavePort;
- CGrafPtr theCPort;
- long result;
- Boolean colorSystem;
-
- if ( colorSystem = (((message == wDraw) || (message == wHit))
- && WindData.hasCQD) ) {
- GetPort( &wpSavePort );
- GetCWMgrPort( &theCPort );
- SetPort( (GrafPtr)theCPort );
- }
- // This sets up the appropriate drawing environment, but only for those
- // messages for which we actually need to draw.
-
- switch( message ) {
- case wDraw: DoWDraw( theWindow, param & 0xFFFF );
- break;
- // There's a tech note that says that for the draw message, only
- // the low-order word of param is set correctly, so we should do
- // this (& 0xFFFF) to make sure we're looking at the correct value.
-
- case wHit: result = DoWHit( theWindow, param );
- break;
-
- case wCalcRgns: DoWCalcRgns( theWindow, param );
- break;
-
- case wNew: DoWInit( varCode, theWindow, param );
- break;
-
- case wDispose: DoWDispose( theWindow, param );
- break;
-
- // case wGrow: DoWGrow( theWindow, param );
- // break;
- // case wDrawGIcon: DoWDrawGIcon( theWindow, param );
- // break;
- // I don't allow of a grow box in a windoid. If you want one, you will
- // have to implement these two routines.
- }
-
- if ( colorSystem )
- SetPort( wpSavePort );
-
- return result;
- }
-
- //*****************************************************************************
- // Environment-determining Routines
- //-----------------------------------------------------------------------------
- // These use SysEnvirons so we don't have to rely on Gestalt being available
- // and so MPW won't include that code in our resource.
-
- short HasSystem7() {
- SysEnvRec theWorld;
- long theSysVers = 0;
-
- if ( SysEnvirons( 1, &theWorld ) == noErr )
- theSysVers = (long)theWorld.systemVersion;
-
- return( theSysVers >= 0x0700 );
- }
-
- //-----------------------------------------------------------------------------
-
- short HasCQDraw() {
- SysEnvRec theWorld;
-
- if ( (SysEnvirons( 1, &theWorld ) == noErr) && theWorld.hasColorQD )
- return 1;
-
- return 0;
- }
-
- //*****************************************************************************
- // Color Mixing Routines
- //-----------------------------------------------------------------------------
-
- void GetWctbColor( short partCode, RGBColor *theColor ) {
- // Given a partCode, return the RGBColor associated with it. (Using the
- // default window color table.)
-
- AuxWinHandle awHndl;
- short junkResult;
-
- junkResult = GetAuxWin( nil, &awHndl );
- *theColor = (**(WCTabHandle)((**awHndl).awCTable)).ctTable[partCode].rgb;
- }
-
- //-----------------------------------------------------------------------------
-
- void SetWctbColor( short partCode ) {
- RGBColor theColor;
-
- GetWctbColor( partCode, &theColor );
- RGBForeColor( &theColor );
- }
-
- //-----------------------------------------------------------------------------
- #pragma processor 68020
- // Note: this should be okay because this will only be called if we are
- // doing System 7 color, which requires Color Quickdraw, which is only
- // available on systems with 68020's or better. Again, this is done to
- // reduce code size. If it isn't compiled this way, several routines will
- // be added to handle the long integer arithmetic. We would like to avoid
- // that.
-
- void MixColor( const RGBColor *lightColor, const RGBColor *darkColor,
- short shade, RGBColor *result ) {
- shade = 0x0F - shade;
- // This is necessary because we give shades between light and
- // dark (0% is light), but for colors, $0000 is black and $FFFF
- // is dark.
-
- result->red = ((lightColor->red - darkColor->red) * shade / 15)
- + darkColor->red;
- result->green = ((lightColor->green - darkColor->green) * shade / 15)
- + darkColor->green;
- result->blue = ((lightColor->blue - darkColor->blue) * shade / 15)
- + darkColor->blue;
- }
-
- #pragma processor 68000
- //-----------------------------------------------------------------------------
-
- void AvgWctbColor( short light, short dark, short shade,
- RGBColor *theColor ) {
- // Mix two parts by the given shade, which is actually a value
- // between 0 (0%) and 15 (100%), return the RGBColor.
-
- RGBColor lightColor;
- RGBColor darkColor;
-
- GetWctbColor( light, &lightColor );
- GetWctbColor( dark, &darkColor );
- MixColor( &lightColor, &darkColor, shade, theColor );
- }
-
- //*****************************************************************************
- // Helper Functions
- //-----------------------------------------------------------------------------
-
- void FrameBox( const Rect *theRect ) {
- Rect tempRect = *theRect;
-
- FrameRect( theRect );
- InsetRect( &tempRect, 1, 1 );
- EraseRect( &tempRect );
- }
-
- //*****************************************************************************
- // Routines to get Rects for title bar parts
- //-----------------------------------------------------------------------------
-
- void GetTitleBar( WindowPeek theWindow, Rect *titleBar ) {
- *titleBar = (**(theWindow->strucRgn)).rgnBBox;
-
- #ifdef ALLOW_VERT
- if (WindData.isHoriz) {
- #endif
- // Horizontal title bar
- titleBar->bottom = titleBar->top + wpTitleHeight;
- titleBar->right -= 1; // shadow compensation
- #ifdef ALLOW_VERT
- } else {
- // Vertical title bar
- titleBar->right = titleBar->left + wpTitleHeight;
- titleBar->bottom -= 1; // shadow compensation
- }
- #endif
- }
-
- //-----------------------------------------------------------------------------
-
- void GetCloseBox( WindowPeek theWindow, Rect *titleRect, Rect *theRect ) {
- #pragma unused( theWindow )
-
- *theRect = *titleRect;
-
- InsetRect( theRect, 2, 2 );
- #ifdef ALLOW_VERT
- if (WindData.isHoriz)
- theRect->left += 4;
- else
- theRect->top += 4;
- #else
- theRect->left += 4;
- #endif
-
- theRect->bottom = theRect->top + wpTitleHeight - 4;
- theRect->right = theRect->left + wpTitleHeight - 4;
- }
-
- //-----------------------------------------------------------------------------
- #ifdef MFI_ZOOMBOX
-
- void GetZoomBox( WindowPeek theWindow, Rect *titleRect, Rect *theRect ) {
- *theRect = *titleRect;
-
- InsetRect( theRect, 2, 2 );
- #ifdef ALLOW_VERT
- if ( WindData.isHoriz ) // Horizontal titlebar
- theRect->right -= 4;
- else // Vertical titlebar
- theRect->bottom -= 4;
- #else // always Horizontal
- theRect->right -= 4;
- #endif
-
- theRect->top = theRect->bottom - wpTitleHeight + 4;
- theRect->left = theRect->right - wpTitleHeight + 4;
- }
-
- //*****************************************************************************
- // SetZoomRects
- //-----------------------------------------------------------------------------
- // This routine can be changed to do a window that zooms in another fashion
-
- void SetZoomRects( WindowPeek theWindow ) {
- Rect theRect;
- GrafPtr savePort;
-
- if ( WindData.hasZoom ) {
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
- theRect = theWindow->port.portRect;
- LocalToGlobal( (Point*)&(theRect.top) );
- LocalToGlobal( (Point*)&(theRect.bottom) );
- SetPort( savePort );
-
- WindData.wState.stdState = theRect;
- if ( WindData.isHoriz ) // Horizontal titlebar
- theRect.bottom = theRect.top + wpSmallZoom;
- else // Vertical titlebar
- theRect.right = theRect.left + wpSmallZoom;
- WindData.wState.userState = theRect;
- // the stdState and user state might be backwards from how they
- // would normally be used by an application. Check this for your
- // own use and change them if necessary.
- }
- }
-
- #endif
- //*****************************************************************************
- // DoWInit -- Windoid initialization
- //-----------------------------------------------------------------------------
-
- void DoWInit( short varCode, WindowPeek theWindow, long param ) {
- #pragma unused( param )
-
- Handle zoomStuff;
-
- theWindow->spareFlag = false;
- zoomStuff = NewHandle( sizeof(WindoidData) );
- if ( zoomStuff ) {
- theWindow->spareFlag = true;
- theWindow->dataHandle = zoomStuff;
- WindData.closeToggle = 0;
- WindData.hasCQD = HasCQDraw();
- WindData.isSystem7 = HasSystem7();
- #ifdef MACAPP_STYLE
- WindData.isHoriz = true; // MacApp doesn't do vertical titlebars
- WindData.ignoreHilite = !((kMacApp_toggleTBar & varCode) != 0);
- #else
- WindData.isHoriz = ((7 & varCode) == 0);
- WindData.ignoreHilite = false;
- #endif
-
- #ifdef MFI_ZOOMBOX
- WindData.zoomToggle = 0;
- #ifdef MACAPP_STYLE // these constants are actually the same
- WindData.hasZoom = ((kMacApp_hasZoom & varCode) != 0);
- #else
- WindData.hasZoom = ((zoomDocProc & varCode) != 0);
- #endif
- SetZoomRects( theWindow );
- #endif
-
- #ifdef ALWAYS_HILITE
- WindData.ignoreHilite = true;
- #endif
- }
- }
-
- //*****************************************************************************
- // DoWDispose -- Windoid disposal
- //-----------------------------------------------------------------------------
-
- void DoWDispose( WindowPeek theWindow, long param ) {
- #pragma unused( param )
-
- if ( theWindow->dataHandle )
- DisposHandle( theWindow->dataHandle );
- }
-
- //*****************************************************************************
- // DoWHit -- Windoid hit routine
- //-----------------------------------------------------------------------------
-
- long DoWHit( WindowPeek theWindow, long param ) {
- Rect theStdRect;
- Rect theUsrRect;
- Rect titleRect;
- Rect contentRect;
- Rect theRect;
- Point hitPt;
- long result;
- #ifdef MFI_ZOOMBOX
- short zoomedNorm;
- #endif
-
- hitPt.v = HiWord( param );
- hitPt.h = LoWord( param );
-
- if ( PtInRgn( hitPt, theWindow->contRgn ) )
- result = wInContent;
- else {
- GetTitleBar( theWindow, &titleRect );
- if ( PtInRect( hitPt, &titleRect ) ) {
- result = wInDrag;
- if ( WindData.ignoreHilite || theWindow->hilited ) {
- GetCloseBox( theWindow, &titleRect, &theRect );
- if ( PtInRect( hitPt, &theRect ) )
- result = wInGoAway;
- #ifdef MFI_ZOOMBOX
- else if ( WindData.hasZoom ) {
- GetZoomBox( theWindow, &titleRect, &theRect );
- if ( PtInRect( hitPt, &theRect ) ) {
- contentRect = (**(theWindow->contRgn)).rgnBBox;
-
- if ( WindData.isHoriz ) // Horizontal
- zoomedNorm = ( (contentRect.bottom - contentRect.top)
- > (wpSmallZoom + 3) );
- else // Vertical
- zoomedNorm = ( (contentRect.right - contentRect.left)
- > (wpSmallZoom + 3) );
-
- if ( zoomedNorm ) // Make Small
- result = wInZoomIn;
- else // Make Normal
- result = wInZoomOut;
-
- // Calculate Offset for Zoom Rects
- theStdRect = WindData.wState.stdState;
- theUsrRect = WindData.wState.userState;
-
- OffsetRect( &(WindData.wState.stdState), contentRect.left
- - theStdRect.left, contentRect.top - theStdRect.top );
- OffsetRect( &(WindData.wState.userState), contentRect.left
- - theUsrRect.left, contentRect.top - theUsrRect.top );
- }
- }
- #endif
- }
- } else
- result = wNoHit;
- }
- return result;
- } // DoWHit
-
- //*****************************************************************************
- // DoWDraw -- Windoid drawing routines
- //-----------------------------------------------------------------------------
-
- void DrawCloseBox( short variation, Rect *theRect ) {
- RGBColor theColor;
- Rect tempRect;
-
- switch ( variation ) {
- case blackandwhite:
- FrameBox( theRect );
- break;
-
- case sys6color:
- SetWctbColor( wHiliteColor );
- GetWctbColor( wTitleBarColor, &theColor );
- RGBBackColor( &theColor );
- FrameBox( theRect );
- break;
-
- case sys7color:
- SetWctbColor( wTingeLight );
- PaintRect( theRect );
-
- SetWctbColor( wTingeDark );
-
- MoveTo( theRect->right - 1, theRect->top );
- LineTo( theRect->left, theRect->top );
- LineTo( theRect->left, theRect->bottom - 1 );
-
- MoveTo( theRect->right - 2, theRect->top + 2 );
- LineTo( theRect->right - 2, theRect->bottom - 2 );
- LineTo( theRect->left + 2, theRect->bottom - 2 );
-
- AvgWctbColor( wHiliteColorLight, wHiliteColorDark,
- wCloseBoxColor, &theColor );
- RGBForeColor( &theColor );
- tempRect = *theRect;
- InsetRect( &tempRect, 2, 2 );
- PaintRect( &tempRect );
-
- break;
- }
-
- }
-
- //*****************************************************************************
- // DrawZoomBox -- Draw zoom box
- //-----------------------------------------------------------------------------
- #ifdef MFI_ZOOMBOX
-
- void DrawZoomBox( short variation, Rect *theRect ) {
- Rect tempRect;
- RGBColor theColor;
-
- switch ( variation ) {
- case blackandwhite:
- case sys6color:
- if ( variation != blackandwhite ) {
- SetWctbColor( wHiliteColor );
- GetWctbColor( wTitleBarColor, &theColor );
- RGBBackColor( &theColor );
- }
- FrameBox( theRect );
- tempRect = *theRect;
- tempRect.bottom -= 3;
- tempRect.right -= 3;
- FrameRect( &tempRect );
- break;
-
- case sys7color:
- DrawCloseBox( variation, theRect );
- SetWctbColor( wTingeDark );
-
- MoveTo(theRect->right - 4, theRect->top + 2);
- LineTo(theRect->right - 4, theRect->bottom - 4);
- LineTo(theRect->left + 2, theRect->bottom - 4);
- break;
- }
- }
-
- #endif
- //*****************************************************************************
- // DrawXedBox -- Draw close or zoom box with an X in it (or inverted in B&W)
- //-----------------------------------------------------------------------------
-
- void DrawXedBox( short variation, Rect *theRect ) {
- RGBColor theColor;
-
- switch ( variation ) {
- case blackandwhite:
- PaintRect( theRect );
- break;
-
- case sys6color:
- SetWctbColor( wHiliteColor );
- PaintRect( theRect );
- break;
-
- case sys7color:
- AvgWctbColor( wTingeLight, wTingeDark, wXedBoxPct, &theColor );
- RGBForeColor( &theColor );
- PaintRect( theRect );
-
- SetWctbColor( wFrameColor );
- FrameRect( theRect );
-
- MoveTo( theRect->left, theRect->top ); // Draw the 'X'
- LineTo( theRect->right - 1, theRect->bottom - 1 );
- MoveTo( theRect->right - 1, theRect->top );
- LineTo( theRect->left, theRect->bottom - 1 );
- break;
- }
- }
-
- //*****************************************************************************
- // DrawTitlePat -- Draw pattern into the title bar
- //-----------------------------------------------------------------------------
-
- void DrawTitlePatPat( Rect titleRect ) {
- // This routine actually draws the pattern into the titlebar. Note: it
- // takes a Rect as a parameter (not by address) because it goes ahead and
- // modifies it. I figured this was no worse than needing to copy it into
- // a local variable, so I went ahead and did it this way.
-
- Pattern titlePat;
- Point corner;
- char *patPtr;
- char patChar1;
- char patChar2;
- short i;
-
- SetPt( &corner, titleRect.left, titleRect.top );
- LocalToGlobal( &corner );
-
- if ( corner.v % 2 == 0 ) {
- patChar1 = 0x55;
- patChar2 = 0x00;
- } else {
- patChar1 = 0x00;
- patChar2 = 0x55;
- }
- if ( corner.h % 2 == 0 ) {
- patChar1 = patChar1 << 1;
- patChar2 = patChar2 << 1;
- }
-
- patPtr = (char *)&titlePat;
- for ( i = 0 ; i < 8 ; i += 2 ) {
- patPtr[i] = patChar1;
- patPtr[i+1] = patChar2;
- }
- // Choose correct pattern, depending on position of window in global
- // coordinates.
-
- InsetRect( &titleRect, 1, 1 );
- FillRect( &titleRect, (ConstPatternParam)&titlePat );
- }
-
- //-----------------------------------------------------------------------------
-
- void DrawTitlePat( short variation, Rect *titleRect ) {
- RGBColor theColor;
-
- switch ( variation ) {
- case blackandwhite:
- ForeColor( blackColor );
- BackColor( whiteColor );
- break;
-
- case sys6color:
- SetWctbColor( wHiliteColor );
- GetWctbColor( wTitleBarColor, &theColor );
- RGBBackColor( &theColor );
- break;
-
- case sys7color:
- AvgWctbColor( wHiliteColorLight, wHiliteColorDark,
- wTitleBarLightPct, &theColor );
- RGBBackColor( &theColor );
- AvgWctbColor( wHiliteColorLight, wHiliteColorDark,
- wTitleBarDarkPct, &theColor );
- RGBForeColor( &theColor );
- break;
- }
-
- DrawTitlePatPat( *titleRect );
- }
-
- //*****************************************************************************
- // CheckDisplay -- Check to see if we are using color title bars
- //-----------------------------------------------------------------------------
-
- Boolean CheckAvailable( short light, short dark, short count, short *ramp ) {
- // Given a light and dark index value, a count, and and an array of
- // 'percentage' values (0x0 to 0xF, or 0 to 15), see if each of the
- // values in the ramp maps to a different color on the screen. If not,
- // we need to use black-and-white.
-
- RGBColor theColor;
- short i;
- short result = true;
- short colorIndex = -1;
- short lastIndex;
-
- for ( i = 0 ; (i < count) && (result == true) ; i++ ) {
- AvgWctbColor( light, dark, ramp[i], &theColor );
- lastIndex = colorIndex;
- colorIndex = Color2Index( &theColor );
- if ( (i > 0) && (colorIndex == lastIndex) )
- result = false;
- }
- return result;
- }
-
- //-----------------------------------------------------------------------------
-
- short CheckDisplay( short theDepth, short deviceFlags,
- GDHandle targetDevice, WindowPeek theWindow ) {
- Boolean inColor;
- short result;
- RGBColor testColor;
- GDHandle saveDevice;
- short list[5];
- // Make sure this array is allcated big enough for the largest ramp.
-
- inColor = WindData.hasCQD && (deviceFlags & (0x0001 << gdDevType));
-
- result = blackandwhite; // assume Black and White
- if ( (theDepth >= 8) || (!inColor && (theDepth >= 4)) ) {
- if ( !WindData.isSystem7 )
- result = sys6color; // System 6.0.x Color
- else {
- GetWctbColor( wTingeLight, &testColor );
- if ( testColor.red && testColor.green && testColor.blue )
- // check for B&W control panel setting, otherwise:
- result = sys7color; // System 7.0 Color
- }
- }
- // Note: Since I didn't find another way to see if the user had changed
- // the settings in the Color control panel to the Black-and-white setting,
- // I actually check to see if the rgb components of the light tinge color
- // are non-zero (which seemed to be the case with that setting).
-
- if ( (result == sys7color) && (theDepth == 8) ) {
- result = blackandwhite;
- saveDevice = GetGDevice();
- SetGDevice( targetDevice );
- list[0] = 0x00;
- list[1] = 0x07;
- list[2] = 0x08;
- list[3] = 0x0A;
- list[4] = 0x0D;
- if ( CheckAvailable( wHiliteColorLight, wHiliteColorDark, 5, list ) ) {
- list[0] = 0x00;
- list[1] = 0x01;
- list[2] = 0x04;
- if ( CheckAvailable( wTitleBarLight, wTitleBarDark, 3, list ) ) {
- list[0] = 0x00;
- list[1] = 0x04;
- list[2] = 0x0F;
- if ( CheckAvailable( wTingeLight, wTingeDark, 3, list ) )
- result = sys7color;
- }
- }
- SetGDevice( saveDevice );
- }
- // This part checks to see if there are 'enough' colors to draw the
- // title bar in color under System 7. It is supposed to do so in the
- // same way that Apple's system WDEF does. I essentially took the
- // assembly code that Apple released and tried to make this use the
- // same algorithm. Note: the values in list for the first CheckAvailable
- // call are set up in the variable declaration in the top of the routine.
- // Don't you just LOVE what C lets you do?
-
- return result;
- }
-
- //*****************************************************************************
-
- pascal void WindoidDrawLoop( short depth, short deviceFlags,
- GDHandle targetDevice, WDLDataPtr userData) {
- #pragma unused( targetDevice )
- // This routine actually does the real work of the drawing of stuff into
- // the window.
-
- Rect titleRect;
- Rect tempRect;
- RGBColor theColor;
- WindowPeek theWindow;
- short fancy;
-
- theWindow = userData->wdlWindow;
- fancy = CheckDisplay(depth, deviceFlags, targetDevice, theWindow);
-
- if ( theWindow->visible )
- switch ( userData->wdlParam ) {
- case 0:
- BackColor( whiteColor );
-
- // DRAW TITLEBAR
- GetTitleBar( theWindow, &titleRect );
- if ( fancy == sys7color )
- if ( WindData.ignoreHilite || theWindow->hilited )
- SetWctbColor( wFrameColor );
- else {
- AvgWctbColor( wHiliteColorLight, wHiliteColorDark,
- wInactiveFramePct, &theColor );
- RGBForeColor( &theColor );
- }
- else if ( fancy == sys6color )
- SetWctbColor( wFrameColor );
- else
- ForeColor( blackColor );
- FrameRect(&titleRect);
-
- if ( WindData.ignoreHilite || theWindow->hilited )
- DrawTitlePat( fancy, &titleRect );
- else {
- tempRect = titleRect;
- InsetRect( &tempRect,1,1 );
- EraseRect( &tempRect );
- }
-
- if ( WindData.ignoreHilite || theWindow->hilited ) {
-
- // DRAW CLOSE BOX
- if ( theWindow->goAwayFlag ) {
- GetCloseBox( theWindow, &titleRect, &tempRect );
- DrawCloseBox( fancy, &tempRect );
- }
- // Note: I have seen at least one windoid WDEF that is used
- // by some applications that does not utilize this flag.
- // In that case, I think it always had a close box (or it
- // might even have used the varcode to determine this, but
- // that wouldn't seem to be a good thing to do). Anyway, if
- // you always want the close box, just comment out the 'if'
- // line (and the close brace line) above.
-
- #ifdef MFI_ZOOMBOX
- // DRAW ZOOM BOX
- if ( WindData.hasZoom ) {
- GetZoomBox( theWindow, &titleRect, &tempRect );
- DrawZoomBox( fancy, &tempRect );
- }
- #endif
- }
-
- // DRAW CONTENT FRAME AND SHADOW
- tempRect = (**(theWindow->strucRgn)).rgnBBox;
-
- tempRect.bottom = tempRect.bottom - 1;
- tempRect.right = tempRect.right - 1;
- if (fancy == sys7color)
- if ( WindData.ignoreHilite || theWindow->hilited )
- SetWctbColor( wFrameColor );
- else {
- AvgWctbColor( wHiliteColorLight, wHiliteColorDark,
- wInactiveFramePct, &theColor );
- RGBForeColor( &theColor );
- }
- else if ( fancy == sys6color )
- SetWctbColor( wFrameColor );
- else // black-and-white
- ForeColor( blackColor );
- FrameRect( &tempRect );
- // If the window is not hilited, this will use a gray shade
- // to draw the window outline in System 7 color.
-
- ForeColor( blackColor ); // draw shadow
- MoveTo( tempRect.right, tempRect.top+1 );
- LineTo( tempRect.right, tempRect.bottom );
- LineTo( tempRect.left + 1, tempRect.bottom );
- break;
-
- case wInGoAway: // toggle go-away
- GetTitleBar( theWindow, &titleRect );
- GetCloseBox( theWindow, &titleRect, &tempRect );
- if ( WindData.closeToggle )
- DrawCloseBox( fancy, &tempRect );
- else
- DrawXedBox( fancy, &tempRect );
- break;
-
- #ifdef MFI_ZOOMBOX
- default:
- if ( WindData.hasZoom ) { // toggle zoom box
- GetTitleBar( theWindow, &titleRect );
- GetZoomBox( theWindow, &titleRect, &tempRect );
- if ( WindData.zoomToggle )
- DrawZoomBox( fancy, &tempRect );
- else
- DrawXedBox( fancy, &tempRect );
- }
- #endif
- }
- ForeColor( blackColor );
- BackColor( whiteColor );
- } // WindoidDrawLoop
-
- //-----------------------------------------------------------------------------
-
- void DoWDraw( WindowPeek theWindow, long param ) {
- WDLDataRec theUserData;
- GrafPtr savePort;
- RgnHandle drawRgn;
- Rect theRect;
- GDHandle theDevice;
- PixMapHandle thePixMap;
- short theDepth;
- short inColor;
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
- drawRgn = theWindow->strucRgn;
- SetPort( savePort );
-
- theUserData.wdlWindow = theWindow;
- theUserData.wdlParam = param;
-
- if ( WindData.isSystem7 ) {
- DeviceLoop( drawRgn, (DeviceLoopDrawingProcPtr)WindoidDrawLoop,
- (long)&theUserData, (DeviceLoopFlags)0 );
- } else {
- theDepth = 1;
- inColor = 0;
- if ( theWindow && WindData.hasCQD ) {
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
- theRect = ((GrafPtr)theWindow)->portRect;
- LocalToGlobal( (Point*)&theRect.top );
- LocalToGlobal( (Point*)&theRect.bottom );
- theDevice = GetMaxDevice( &theRect );
- SetPort( savePort );
-
- if ( theDevice ) {
- thePixMap = (**theDevice).gdPMap;
- theDepth = (**thePixMap).pixelSize;
- WindoidDrawLoop( theDepth, (**theDevice).gdFlags,
- theDevice, &theUserData );
- } else
- WindoidDrawLoop( 1, 0, nil, &theUserData );
-
- // Do this for pre-System 7. we call WindoidDrawLoop directly, giving
- // it the information on the device with maximum depth, hoping that
- // the results will be okay. Only reason it might not be is if you
- // have a System 6 color window that crosses two monitors that have
- // differing environments where one doesn't have enough colors to
- // show the color version. Here, the problem will be only cosmetic,
- // though. Note: I could have done my own device loop for this case,
- // but I figured it wasn't common enough for the expense.
- } else {
- WindoidDrawLoop( 1, 0, nil, &theUserData );
-
- // Do this for 68000's
- }
- }
-
- if ( theWindow->visible )
- switch ( param ) {
- case 0:
- break;
-
- case wInGoAway: // toggle go-away
- WindData.closeToggle = !(WindData.closeToggle);
- break;
-
- #ifdef MFI_ZOOMBOX
- default:
- if ( WindData.hasZoom ) // toggle zoom box
- WindData.zoomToggle = !(WindData.zoomToggle);
- #endif
- }
- if ( WindData.hasCQD ) { // restore the color environment to default
- ForeColor( blackColor );
- BackColor( whiteColor );
- }
-
- } // DoWDraw
-
- //*****************************************************************************
- // DoWCalcRgns -- Windoid region calculating routine
- //-----------------------------------------------------------------------------
-
- void DoWCalcRgns( WindowPeek theWindow, long param ) {
- #pragma unused( param )
-
- short hOfst, vOfst;
- Rect theContentRect;
- Rect theStructRect;
- Rect tempRect;
- RgnHandle tempRgn;
- GrafPtr savePort;
-
- GetPort( &savePort );
- SetPort( (GrafPtr)theWindow );
- theContentRect = ((GrafPtr)theWindow)->portRect;
- hOfst = ((GrafPtr)theWindow)->portBits.bounds.left;
- vOfst = ((GrafPtr)theWindow)->portBits.bounds.top;
- OffsetRect( &theContentRect, -hOfst, -vOfst );
- RectRgn( theWindow->contRgn, &theContentRect );
- theStructRect = theContentRect;
- InsetRect( &theStructRect, -1, -1 );
- if ( WindData.isHoriz )
- theStructRect.top -= wpTitleHeight - 1;
- else
- theStructRect.left -= wpTitleHeight - 1;
- RectRgn( theWindow->strucRgn, &theStructRect );
- tempRect = theStructRect;
- OffsetRect( &tempRect, 1, 1 );
- tempRgn = NewRgn();
- RectRgn( tempRgn, &tempRect );
- UnionRgn( tempRgn, theWindow->strucRgn, theWindow->strucRgn );
- DisposeRgn( tempRgn );
-
- SetPort( savePort );
- }
-
- //*****************************************************************************